﻿using System.Text;
using Jupiter.Infrastructure.Exceptions;
using Jupiter.Infrastructure.Responses;
using Newtonsoft.Json;
using Wips.Infrastructure.Helpers;
using Wips.Infrastructure.Interfaces;
using Wips.Infrastructure.Model;
using Wips.Infrastructure.Realizes;

namespace Wips.Infrastructure
{
    public static class Extensions
    {
        /// <summary>
        /// 获取请求上的querystring
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetRequestQueryString(HttpContext context)
        {
            var query = context.Request.Query.OrderBy(c => c.Key);
            var queryString = new StringBuilder();
            foreach (var param in query)
            {
                queryString.Append($"{param.Key}={param.Value}&");
            }
            // 移除最后一个"&"字符
            if (queryString.Length > 0)
            {
                queryString.Remove(queryString.Length - 1, 1);
            }
            return queryString.ToString();
        }

        /// <summary>
        /// 获取请求的body
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetRequestBodyString(HttpContext context)
        {
            try
            {
                context.Request.EnableBuffering();  // 允许多次读取请求体

                using var reader = new StreamReader(context.Request.Body, leaveOpen: true);
                var body = reader.ReadToEndAsync().Result;

                // 重置请求体的位置，以便后续的中间件可以读取它
                context.Request.Body.Position = 0;

                return body;
            }
            catch (Exception)
            {

                return "";
            }

        }
        public static string GetReadableFileSize(long length)
        {
            string[] sizes = { "B", "KB", "MB", "GB", "TB" };
            int order = 0;
            while (length >= 1024 && order < sizes.Length - 1)
            {
                order++;
                length = length / 1024;
            }

            return String.Format("{0:0.##} {1}", length, sizes[order]);
        }

        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="app"></param>
        public static IEndpointRouteBuilder MapAgentSever(this IEndpointRouteBuilder app)
        {
            // 健康检查
            app.MapGet(Consts.MapHealthCheckPath, context =>
            {
                context.Response.WriteAsync("ok");
                return Task.CompletedTask;
            });
            // 获取磁盘列表
            app.MapGet(Consts.MapGetRootPath, context =>
            {

                DriveInfo[] allDrives = DriveInfo.GetDrives();
                context.Response.WriteAsJsonAsync(new ApiResult<List<string>>
                {
                    Success = true,
                    Message = "获取成功",
                    Data = allDrives.Select(p => p.Name).ToList()
                });
                return Task.CompletedTask;
            });
            // 获取文件夹列表
            app.MapGet(Consts.MapGetFolderListPath, context =>
            {
                try
                {
                    var req = context.Request;
                    var path = req.Query["path"].ToString();
                    var data = new List<DirectoryModel>();
                    // 获取所有文件夹
                    string[] directories = Directory.GetDirectories(path);
                    foreach (string directory in directories)
                    {
                        if ((File.GetAttributes(directory) & FileAttributes.Hidden) == FileAttributes.Hidden)
                        {
                            // 这是一个隐藏的文件夹，跳过
                            continue;
                        }
                        var directoryInfo = new DirectoryInfo(directory);
                        var canRead = HasReadPermissionOnDir(directoryInfo);
                        var canWrite = HasWritePermissionOnDir(directoryInfo);
                        data.Add(new DirectoryModel
                        {
                            Path = directory,
                            Type = EnumDirectorType.Directory,
                            CanRead = canRead,
                            CanWrite = canWrite
                        });
                    }

                    // 获取所有文件
                    string[] files = Directory.GetFiles(path);
                    foreach (string file in files)
                    {
                        if ((File.GetAttributes(file) & FileAttributes.Hidden) == FileAttributes.Hidden)
                        {
                            // 这是一个隐藏的文件，跳过
                            continue;
                        }

                        var fileInfo = new FileInfo(file);
                        var canRead = HasReadPermissionOnFile(fileInfo);
                        var canWrite = HasWritePermissionOnFile(fileInfo);
                        data.Add(new DirectoryModel
                        {
                            Path = file,
                            Type = EnumDirectorType.File,
                            CanRead = canRead,
                            CanWrite = canWrite,
                            Size = GetReadableFileSize(fileInfo.Length),
                            KbSize = fileInfo.Length / 1024
                        });
                    }
                    context.Response.WriteAsJsonAsync(new ApiResult<List<DirectoryModel>>
                    {
                        Success = true,
                        Message = "获取成功",
                        Data = data
                    });
                    return Task.CompletedTask;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    context.Response.WriteAsJsonAsync(new ApiResult<string>()
                    {
                        Success = false,
                        Message = "获取失败！" + e.Message
                    });
                    return Task.CompletedTask;
                }
            });
            // 备份指定文件到一个zip里
            app.MapPost(Consts.MapAgentBackUpPath, context =>
            {
                var req = context.Request;
                var bodyStr = "";
                using (StreamReader reader = new StreamReader(req.Body, Encoding.UTF8, true, 1024, true))
                {
                    bodyStr = reader.ReadToEndAsync().Result;
                }

                var body = JsonConvert.DeserializeObject<BackupRequest>(bodyStr);
                if (body == null || body.Paths.Count == 0 || string.IsNullOrEmpty(body.ServerName))
                {
                    context.Response.WriteAsJsonAsync(new ApiResult<string>
                    {
                        Success = false,
                        Message = "参数错误：" + bodyStr
                    }); ;
                    return Task.CompletedTask;
                }
                var backPath = (Path.Combine(".\\backup\\", body.ServerName));
                var name = DateTime.Now.ToString("yyyyMMddHHmmss") + ".zip";
                ZipHelper.CreateCustomZip(body.RootPath, backPath, name, body.Paths);
                context.Response.WriteAsJsonAsync(new ApiResult<string>
                {
                    Success = true,
                    Message = "备份成功",
                    Data = Path.Combine(backPath, name)
                });
                return Task.CompletedTask;
            });

            // 获取指定zip文件的文件列表
            app.MapGet(Consts.MapGetZipFileInfoList, context =>
            {
                var req = context.Request;
                var path = req.Query["path"].ToString();
                var data = new List<DirectoryModel>();
                var b = File.Exists(path);
                if (!b)
                {
                    context.Response.WriteAsJsonAsync(new ApiResult<List<DirectoryModel>>
                    {
                        Success = false,
                        Message = "文件不存在，请检查是否已删除！",
                    });
                    return Task.CompletedTask;
                }
                data = ZipHelper.ListZipContents(path);
                context.Response.WriteAsJsonAsync(new ApiResult<List<DirectoryModel>>
                {
                    Success = true,
                    Message = "获取成功",
                    Data = data
                });

                return Task.CompletedTask;
            });

            // 执行发布
            app.MapPost(Consts.MapPublish, context =>
            {

                try
                {
                    var req = context.Request;
                    var bodyStr = "";
                    using (StreamReader reader = new StreamReader(req.Body, Encoding.UTF8, true, 1024, true))
                    {
                        bodyStr = reader.ReadToEndAsync().Result;
                    }

                    var body = JsonConvert.DeserializeObject<PublishRequest>(bodyStr);
                    var b = File.Exists(body!.ZipPath);
                    if (!b)
                    {
                        context.Response.WriteAsJsonAsync(new ApiResult<List<DirectoryModel>>
                        {
                            Success = false,
                            Message = "文件不存在，请检查是否已删除！",
                        });
                        return Task.CompletedTask;
                    }
                    ZipHelper.ExtractAndOverwriteZipFile(body!.ZipPath, body.RootPath);

                    context.Response.WriteAsJsonAsync(new ApiResult<string>
                    {
                        Success = true,
                        Message = "发布成功！"
                    });
                    return Task.CompletedTask;
                }
                catch (Exception ex)
                {

                    context.Response.WriteAsJsonAsync(new ApiResult<List<DirectoryModel>>
                    {
                        Success = false,
                        Message = ex.Message + ";" + ex.StackTrace,

                    });
                    return Task.CompletedTask;
                }

            });

            // 执行命令
            app.MapPost(Consts.MapRunScript, context =>
            {
                var req = context.Request;
                var bodyStr = "";
                using (StreamReader reader = new StreamReader(req.Body, Encoding.UTF8, true, 1024, true))
                {
                    bodyStr = reader.ReadToEndAsync().Result;
                }

                var body = JsonConvert.DeserializeObject<RunScriptRequest>(bodyStr);
                if (body == null || string.IsNullOrEmpty(body.Command))
                {
                    context.Response.WriteAsJsonAsync(new ApiResult<string>
                    {
                        Success = false,
                        Message = "参数错误：" + bodyStr
                    }); ;
                    return Task.CompletedTask;
                }
                var command = body.Command.Split(' ');
                foreach (var item in command)
                {
                    if (Consts.NotSupportCommand.Where(c => c.ToLower().StartsWith(item.ToLower())).Any())
                    {
                        throw new Exception("不支持的命令");
                    }
                    if (Consts.NotSupportKeyWord.Where(c => item.ToLower().Contains(c.ToLower())).Any())
                    {
                        throw new Exception("不支持的关键字");
                    }
                }

                try
                {
                    var result = DiagnosticsHelper.ExecuteCommand(body.Command);
                    context.Response.WriteAsJsonAsync(new ApiResult<string>
                    {
                        Success = true,
                        Message = "执行成功",
                        Data = result
                    });
                }
                catch (Exception ex)
                {
                    context.Response.WriteAsJsonAsync(new ApiResult<string>
                    {
                        Success = false,
                        Message = "执行失败：" + ex.Message,
                        Data = ex.Message
                    });


                }

                return Task.CompletedTask;
            });


            // 获取文件内容
            app.MapGet(Consts.MapGetFileText, context =>
            {
                var req = context.Request;
                var path = req.Query["path"].ToString();
                var data = "";
                var b = File.Exists(path);
                if (!b)
                {
                    context.Response.WriteAsJsonAsync(new ApiResult<string>
                    {
                        Success = false,
                        Message = "文件不存在，请检查是否已删除！",
                    });
                    return Task.CompletedTask;
                }
                // 判断文件大于30kb则不让修改
                var fileInfo = new FileInfo(path);
                if (fileInfo.Length > 50 * 1024)
                {
                    context.Response.WriteAsJsonAsync(new ApiResult<string>
                    {
                        Success = false,
                        Message = "文件过大，不支持在线编辑！",
                    });
                    return Task.CompletedTask;
                }
                data = File.ReadAllText(path);
                context.Response.WriteAsJsonAsync(new ApiResult<string>
                {
                    Success = true,
                    Message = "获取成功",
                    Data = data
                });

                return Task.CompletedTask;
            });

            // 保存文件内容
            app.MapPost(Consts.MapSaveFileText, context =>
            {
                var req = context.Request;
                var bodyStr = "";
                using (StreamReader reader = new StreamReader(req.Body, Encoding.UTF8, true, 1024, true))
                {
                    bodyStr = reader.ReadToEndAsync().Result;
                }

                var body = JsonConvert.DeserializeObject<SaveFileTextRequest>(bodyStr);
                if (body == null || string.IsNullOrEmpty(body.Path) || string.IsNullOrEmpty(body.Content))
                {
                    context.Response.WriteAsJsonAsync(new ApiResult<string>
                    {
                        Success = false,
                        Message = "参数错误：" + bodyStr
                    }); ;
                    return Task.CompletedTask;
                }
                File.WriteAllText(body.Path, body.Content);
                context.Response.WriteAsJsonAsync(new ApiResult<string>
                {
                    Success = true,
                    Message = "保存成功"
                });
                return Task.CompletedTask;
            });


            return app;
        }


        /// <summary>
        /// 添加发布平台主服务
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddPublishMaster(this IServiceCollection services)
        {
            return services;
        }

        /// <summary>
        /// 注册发布平台主服务
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        public static IApplicationBuilder UsePublishMaster(this IApplicationBuilder app)
        {

            return app;
        }

        /// <summary>
        /// 添加发布平台子服务
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddPublishAgent(this IServiceCollection services)
        {
            services.AddSingleton<IPublishAgentService, PublishAgentService>();
            return services;
        }

        /// <summary>
        /// 注册发布子服务
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        public static IApplicationBuilder UsePublishAgent(this IApplicationBuilder app)
        {

            var agentService = app.ApplicationServices.GetService<IPublishAgentService>();
            if (agentService == null)
            {
                throw new CoreException("services.AddPublishAgent未配置！");
            }
            var isRun = agentService.RunAsync().Result;

            return app;
        }


        public static bool HasReadPermissionOnDir(DirectoryInfo directoryInfo)
        {
            try
            {
                directoryInfo.GetDirectories();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public static bool HasWritePermissionOnDir(DirectoryInfo directoryInfo)
        {
            try
            {
                var testFilePath = Path.Combine(directoryInfo.FullName, "testpower.tmp");
                using (File.Create(testFilePath)) { };
                File.Delete(testFilePath);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }


        public static bool HasReadPermissionOnFile(FileInfo fileInfo)
        {
            try
            {
                fileInfo.OpenRead().Close();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public static bool HasWritePermissionOnFile(FileInfo fileInfo)
        {
            try
            {
                fileInfo.OpenWrite().Close();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

    }
}
